﻿using System;
using System.Data;
using System.Collections.Generic;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using POS.BusinessEntities;
using POS.DataObjects;


namespace POS.DataObjectsTest
{
    [TestClass]
    public class DOEntidadTest
    {
        #region Declarations
        private static Database db;
        private const string testUser = "testUser";
        private const int EmpresaId = 1;
        
        #endregion
       
        #region Properties: Non-Public

        private static Database Db
        {
            get
            {
                if (db == null)
                    db = DatabaseFactory.CreateDatabase();
                return db;
            }
        }

        #endregion
        
        #region Test Methods

        #region Marca

        [TestMethod]
        public void GetListMarcaSinFiltro()
        {
            var entityType = TipoEntidad.Marca;
            var ds = Db.ExecuteDataSet(CommandType.Text, "select * from marca where empresaId = " + EmpresaId + " and activo=1");
            var filtro = "";

            var results = new DOEntidad(entityType).GetList(EmpresaId, filtro);
            AssertGetListResult(ds, results, entityType);
        }

        [TestMethod]
        public void DeleteMarca()
        {
            const string name = "TestName";
            var id = CreateMarca(name);

            new DOEntidad(TipoEntidad.Marca).Delete(id, testUser);

            var ds = Db.ExecuteDataSet(CommandType.Text, "select * from marca where marcaId=" + id);
            Assert.IsNotNull(ds);
            Assert.AreEqual(1, ds.Tables.Count);
            Assert.AreEqual(1, ds.Tables[0].Rows.Count);
            var row = ds.Tables[0].Rows[0];
            Assert.AreEqual(false, row["Activo"]);
            Assert.AreEqual(DateTime.Today.ToShortDateString(), DateTime.Parse(row["FechaModificacion"].ToString()).ToShortDateString());
            Assert.AreEqual(testUser, row["ModificadoPor"]);
        }

        [TestMethod]
        public void SaveMarcaNew()
        {
            const string marcaName = "TestMarca";
            Db.ExecuteNonQuery(CommandType.Text, "delete marca where empresaId = " + EmpresaId);
            var marca = new BEEntidad { Nombre = marcaName };
            new DOEntidad(TipoEntidad.Marca).Save(marca, EmpresaId, testUser);

            var ds = Db.ExecuteDataSet(CommandType.Text, "select * from marca where empresaId=" + EmpresaId);
            Assert.IsNotNull(ds);
            Assert.AreEqual(1, ds.Tables.Count);
            Assert.AreEqual(1, ds.Tables[0].Rows.Count);
            var row = ds.Tables[0].Rows[0];
            Assert.IsTrue((int)row["MarcaId"] > 0);
            Assert.AreEqual(marcaName, row["Nombre"]);
            Assert.AreEqual(true, row["Activo"]);
            Assert.AreEqual(testUser, row["ModificadoPor"]);
            Assert.AreEqual(DateTime.Today.ToShortDateString(), DateTime.Parse(row["FechaModificacion"].ToString()).ToShortDateString());
            Assert.AreEqual(DateTime.Today.ToShortDateString(), DateTime.Parse(row["FechaCreacion"].ToString()).ToShortDateString());
        }

        [TestMethod]
        public void SaveMarcaExisting()
        {
            const string marcaName = "TestMarca";
            DeleteMarca(marcaName);
            var marcaId = CreateMarca(marcaName);
            var expectedName = marcaName + DateTime.Now.Ticks;
            var expectedUser = testUser + DateTime.Now.Ticks;
            var marca = new BEEntidad { Id = marcaId, Nombre = expectedName };

            new DOEntidad(TipoEntidad.Marca).Save(marca, EmpresaId, expectedUser);

            var ds = Db.ExecuteDataSet(CommandType.Text, "select * from marca where empresaId=" + EmpresaId);
            Assert.IsNotNull(ds);
            Assert.AreEqual(1, ds.Tables.Count);
            Assert.AreEqual(1, ds.Tables[0].Rows.Count);
            var row = ds.Tables[0].Rows[0];
            Assert.IsTrue((int)row["MarcaId"] > 0);
            Assert.AreEqual(expectedName, row["Nombre"]);
            Assert.AreEqual(true, row["Activo"]);
            Assert.AreEqual(expectedUser, row["ModificadoPor"]);
            Assert.AreEqual(DateTime.Today.ToShortDateString(), DateTime.Parse(row["FechaModificacion"].ToString()).ToShortDateString());
        }

        #endregion

        #region Linea

        [TestMethod]
        public void GetListLineaSinFiltro()
        {
            var entityType = TipoEntidad.Linea;
            var ds = Db.ExecuteDataSet(CommandType.Text, "select * from linea where empresaId = " + EmpresaId + " and activo=1");
            var filtro = "";

            var results = new DOEntidad(entityType).GetList(EmpresaId, filtro);
            AssertGetListResult(ds, results, entityType);
        }

        [TestMethod]
        public void DeleteLinea()
        {
            const string name = "TestName";
            var id = CreateLinea(name);

            new DOEntidad(TipoEntidad.Linea).Delete(id, testUser);

            var ds = Db.ExecuteDataSet(CommandType.Text, "select * from linea where lineaId=" + id);
            Assert.IsNotNull(ds);
            Assert.AreEqual(1, ds.Tables.Count);
            Assert.AreEqual(1, ds.Tables[0].Rows.Count);
            var row = ds.Tables[0].Rows[0];
            Assert.AreEqual(false, row["Activo"]);
            Assert.AreEqual(DateTime.Today.ToShortDateString(), DateTime.Parse(row["FechaModificacion"].ToString()).ToShortDateString());
            Assert.AreEqual(testUser, row["ModificadoPor"]);
        }

        [TestMethod]
        public void SaveLineaNew()
        {
            const string name = "TestName";
            Db.ExecuteNonQuery(CommandType.Text, "delete linea where empresaId = " + EmpresaId);
            var entity = new BEEntidad { Nombre = name };
            new DOEntidad(TipoEntidad.Linea).Save(entity, EmpresaId, testUser);

            var ds = Db.ExecuteDataSet(CommandType.Text, "select * from linea where empresaId=" + EmpresaId);
            Assert.IsNotNull(ds);
            Assert.AreEqual(1, ds.Tables.Count);
            Assert.AreEqual(1, ds.Tables[0].Rows.Count);
            var row = ds.Tables[0].Rows[0];
            Assert.IsTrue((int)row["LineaId"] > 0);
            Assert.AreEqual(name, row["Nombre"]);
            Assert.AreEqual(true, row["Activo"]);
            Assert.AreEqual(testUser, row["ModificadoPor"]);
            Assert.AreEqual(DateTime.Today.ToShortDateString(), DateTime.Parse(row["FechaModificacion"].ToString()).ToShortDateString());
            Assert.AreEqual(DateTime.Today.ToShortDateString(), DateTime.Parse(row["FechaCreacion"].ToString()).ToShortDateString());
        }

        [TestMethod]
        public void SaveLineaExisting()
        {
            const string name = "TestName";
            DeleteLinea(name);
            var id = CreateLinea(name);
            var expectedName = name + DateTime.Now.Ticks;
            var expectedUser = testUser + DateTime.Now.Ticks;
            var marca = new BEEntidad { Id = id, Nombre = expectedName };

            new DOEntidad(TipoEntidad.Linea).Save(marca, EmpresaId, expectedUser);

            var ds = Db.ExecuteDataSet(CommandType.Text, "select * from linea where empresaId=" + EmpresaId);
            Assert.IsNotNull(ds);
            Assert.AreEqual(1, ds.Tables.Count);
            Assert.AreEqual(1, ds.Tables[0].Rows.Count);
            var row = ds.Tables[0].Rows[0];
            Assert.IsTrue((int)row["LineaId"] > 0);
            Assert.AreEqual(expectedName, row["Nombre"]);
            Assert.AreEqual(true, row["Activo"]);
            Assert.AreEqual(expectedUser, row["ModificadoPor"]);
            Assert.AreEqual(DateTime.Today.ToShortDateString(), DateTime.Parse(row["FechaModificacion"].ToString()).ToShortDateString());
        }

        #endregion
       
        #endregion
        
        #region Test Utilities

        public static void AssertGetListResult(DataSet ds, IList<BEEntidad> list, TipoEntidad entityType)
        {
            Assert.AreEqual(ds.Tables[0].Rows.Count, list.Count);
            for (var i = 0; i < list.Count; i++)
            {   
                Assert.AreEqual(list[i].Id, ds.Tables[0].Rows[i][entityType + "Id"]);
                Assert.AreEqual(list[i].Nombre, ds.Tables[0].Rows[i]["Nombre"]);
            }
        }
        
        private static int CreateMarca(string name)
        {
            const int id = 999;
            Db.ExecuteNonQuery(CommandType.Text, "delete marca where marcaId = " + id);
            var sql = "Insert into Marca (MarcaId, EmpresaId, Activo, Nombre, FechaCreacion, FechaModificacion, ModificadoPor) " +
                      "Values (" + id + ", " + EmpresaId + ", 1, '" + name + "', getdate(), getdate(), 'TestUser')";
            Db.ExecuteNonQuery(CommandType.Text, sql);
            return id;
        }

        private static void DeleteMarca(string name)
        {
            Db.ExecuteNonQuery(CommandType.Text, "delete marca where empresaId = " + EmpresaId + " and nombre='" + name + "'");
        }

        private static int CreateLinea(string name)
        {
            const int id = 999;
            Db.ExecuteNonQuery(CommandType.Text, "delete linea where lineaId = " + id);
            var sql = "Insert into Linea (LineaId, EmpresaId, Activo, Nombre, FechaCreacion, FechaModificacion, ModificadoPor) " +
                      "Values (" + id + ", " + EmpresaId + ", 1, '" + name + "', getdate(), getdate(), 'TestUser')";
            Db.ExecuteNonQuery(CommandType.Text, sql);
            return id;
        }

        private static void DeleteLinea(string name)
        {
            Db.ExecuteNonQuery(CommandType.Text, "delete linea where empresaId = " + EmpresaId + " and nombre='" + name + "'");
        }
       
        #endregion
    }
}
